/**
 * 
路径表达式	结果
bookstore	选取 bookstore 元素的所有子节点
/bookstore	选取根元素 bookstore 注释：假如路径起始于正斜杠( / )，则此路径始终代表到某元素的绝对路径！
bookstore/book	选取所有属于 bookstore 的子元素的 book 元素。
//book	选取所有 book 子元素，而不管它们在文档中的位置。
bookstore//book	选择所有属于 bookstore 元素的后代的 book 元素，而不管它们位于 bookstore 之下的什么位置。
//@lang	选取所有名为 lang 的属性。

三、限定语
用来查找某个特定的节点或者包含某个指定的值的节点。以方括号括起。
例如：
路径表达式	结果
/bookstore/book[1]	选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]	选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]	选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]	选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]	选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng']	选取所有 title 元素，且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]	选取所有 bookstore 元素的 book 元素，且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title	选取所有 bookstore 元素中的 book 元素的 title 元素，且其中的 price 元素的值须大于 35.00。

四、通配符
通配符	描述
*	匹配任何元素节点
@*	匹配任何属性节点
node()	匹配任何类型的节点
|          选取若干路径  

例如：
路径表达式	结果
/bookstore/*	选取 bookstore 元素的所有子节点
//*	选取文档中的所有元素
//title[@*]	选取所有带有属性的 title 元素。
//book/title | //book/price	选取所有 book 元素的 tilte 和 price 元素。
//title | //price	选取所有文档中的 title 和 price 元素。
/bookstore/book/title | //price	选取所有属于 bookstore 元素的 book 元素的 title 元素，以及文档中所有的 price 元素。
 
五、函数
名称	结果
ancestor	选取当前节点的所有先辈（父、祖父等）
ancestor-or-self	选取当前节点的所有先辈（父、祖父等）以及当前节点本身
attribute	选取当前节点的所有属性
child	选取当前节点的所有子元素。
descendant	选取当前节点的所有后代元素（子、孙等）。
descendant-or-self	选取当前节点的所有后代元素（子、孙等）以及当前节点本身。
following	选取文档中当前节点的结束标签之后的所有节点。
namespace	选取当前节点的所有命名空间节点
parent	选取当前节点的父节点。
preceding	选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling	选取当前节点之前的所有同级节点。
self	选取当前节点。 路径表达式可以是绝对路径，也可以是相对路径。例如：
绝对位置路径：
/step/step/...
相对位置路径：
step/step/...
其中的每一步又可以是一个表达式，包括：
轴（函数）（axis）
定义所选节点与当前节点之间的树关系
节点测试（node-test）
识别某个轴内部的节点
零个或者更多谓语（predicate）
更深入地提炼所选的节点集
例如：
例子	结果
child::book	选取所有属于当前节点的子元素的 book 节点
attribute::lang	选取当前节点的 lang 属性
child::*	选取当前节点的所有子元素
attribute::*	选取当前节点的所有属性
child::text()	选取当前节点的所有文本子节点
child::node()	选取当前节点的所有子节点
descendant::book	选取当前节点的所有 book 后代
ancestor::book	选择当前节点的所有 book 先辈
ancestor-or-self::book	选取当前节点的所有book先辈以及当前节点（假如此节点是book节点的话）
child::child::price	选取当前节点的所有 price 孙。
 
六、运算符
运算符	描述	实例	返回值
|	计算两个节点集	//book | //cd	返回所有带有 book 和 ck 元素的节点集
+	加法	6 + 4	10
-	减法	6 - 4	2
*	乘法	6 * 4	24
div	除法	8 div 4	2
=	等于	price=9.80	如果 price 是9.80，则返回 true。 如果 price 是9.90，则返回 fasle。
!=	不等于	price!=9.80	如果 price 是 9.90，则返回 true。 如果 price 是 9.98，则返回 fasle。
<	小于	price<9.80	如果price是9.00，则返回true 如果price是9.98，则返回fasle
<=	小于或等于	price<=9.80	如果 price 是9.00，则返回 true。 如果 price 是9.90，则返回 fasle。
>	大于	price>9.80	如果 price 是 9.90，则返回 true。 如果 price 是 9.80，则返回 fasle。
>=	大于或等于	price>=9.80	如果 price 是 9.90，则返回 true。 如果 price 是 9.70，则返回 fasle。
or	或	price=9.80 or price=9.70	如果 price 是 9.80，则返回 true。 如果 price 是 9.50，则返回 fasle。
and	与	price>9.00 and price<9.90	如果 price 是 9.80，则返回 true。 如果 price 是 8.50，则返回 fasle。
mod	计算除法的余数	5 mod 2	1  
七、在Java中使用Xpath
在java1.5中推出了一个javax.xml.xpath包专门用来在java中使用Xpath表达式来读取xml。
1. 数据类型
在学习之前首先需要注意的是：Xpath的数据并不与Java有一一对应关系，Xpath1.0只声明了四种数据类型：
node-set
number
boolean
string
 
对应到java就是：
number 映射为 java.lang.Double
string 映射为 java.lang.String
boolean 映射为 java.lang.Boolean
node-set 映射为 org.w3c.dom.NodeList
http://blog.csdn.net/jefferxun1/article/details/7805062
 */
package test;
import java.io.IOException;
import java.io.InputStream;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.*;
import javax.xml.xpath.*;

public class XPathExample {

	public static void name()  throws ParserConfigurationException, SAXException, 
    IOException, XPathExpressionException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	//	factory.setNamespaceAware(false);
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse("C:/Users/Administrator/Desktop/test.xml");
		System.out.println(doc.getChildNodes().getLength());
		XPathFactory xFactory = XPathFactory.newInstance();
		XPath xpath = xFactory.newXPath();
		XPathExpression expr = xpath.compile("//name/text()");
		Object result = expr.evaluate(doc, XPathConstants.NODESET);
		NodeList nodes = (NodeList) result;
		System.out.println(nodes.getLength());
		for (int i = 0; i < nodes.getLength(); i++) {
			System.out.println(nodes.item(i).getNodeValue());
		}
	}
  public static void main(String[] args) 
   throws ParserConfigurationException, SAXException, 
          IOException, XPathExpressionException {

	   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder builder = dbf.newDocumentBuilder();
    InputStream in = XPathExample.class.getClassLoader().getResourceAsStream("books.xml");
    Document doc = builder.parse(in);
   // Document doc = builder.parse("books.xml");

    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    XPathExpression expr = xpath.compile("/books/book/name");

    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    for (int i = 0; i < nodes.getLength(); i++) {
        //System.out.println(nodes.item(i).getNodeValue()); 
        System.out.println(nodes.item(i).getTextContent());
      //  System.out.println(nodes.item(i).toString());
       // System.out.println(nodes.item(i).getAttributes());
    }

  }

}
